﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Barcode
{
    public static class IDCardValid
    {
        static readonly string[] eccCode = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
        static readonly int[] wi = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };
        //省份
        static string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
        //static string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
        public static string ExchageIDCard15to18(string idCardNo15)
        {
            string temp = idCardNo15.Insert(6, "19");
            char[] idCharArray = temp.ToCharArray();
            if (idCharArray.Length != 17)
                return "";

            int total = 0;
            int i = 0;

            try
            {
                foreach (char ch in idCharArray)
                {
                    total += (Convert.ToInt32(ch) - 48) * wi[i++];
                }
            }
            catch
            {
                return "";
            }

            if (total % 11 > 10)
                return "";

            return temp + eccCode[total % 11];
        }

        /// <summary>
        /// 验证身份证号码
        /// </summary>
        /// <param name="Id">身份证号码</param>
        /// <returns>验证成功为True，否则为False</returns>
        public static bool CheckIDCard(string Id)
        {
            if (Id.Length == 18)
            {
                bool check = CheckIDCard18(Id);
                return check;
            }
            else if (Id.Length == 15)
            {
                bool check = CheckIDCard15(Id);
                return check;
            }
            else
            {
                return false;
            }
        }

        #region 身份证号码验证

        /// <summary>
        /// 验证15位身份证号
        /// </summary>
        /// <param name="Id18">身份证号</param>
        /// <returns>验证成功为True，否则为False</returns>
        private static bool CheckIDCard18(string Id18)
        {
            long n = 0;
            if (long.TryParse(Id18.Remove(17), out n) == false || long.TryParse(Id18.Replace('x', '0').Replace('X', '0'), out n) == false)
            {
                return false;//数字验证
            }

            if (address.IndexOf(Id18.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id18.Substring(6, 8).Insert(6, "-").Insert(4, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            char[] Ai = Id18.Remove(17).ToCharArray();
            int sum = 0;
            for (int i = 0; i < 17; i++)
            {
                sum += wi[i] * int.Parse(Ai[i].ToString());
            }
            int y = -1;
            Math.DivRem(sum, 11, out y);
            if (eccCode[y] != Id18.Substring(17, 1).ToUpper())
            {
                return false;//校验码验证
            }
            return true;//符合GB11643-1999标准
        }

        /// <summary>
        /// 验证18位身份证号
        /// </summary>
        /// <param name="Id15">身份证号</param>
        /// <returns>验证成功为True，否则为False</returns>
        private static bool CheckIDCard15(string Id15)
        {
            long n = 0;
            if (long.TryParse(Id15, out n) == false || n < Math.Pow(10, 14))
            {
                return false;//数字验证
            }
       
            if (address.IndexOf(Id15.Remove(2)) == -1)
            {
                return false;//省份验证
            }
            string birth = Id15.Substring(6, 6).Insert(4, "-").Insert(2, "-");
            DateTime time = new DateTime();
            if (DateTime.TryParse(birth, out time) == false)
            {
                return false;//生日验证
            }
            return true;//符合15位身份证标准
        }
        #endregion
    }
}
